/*
 * @Author: wuqingchun
 * @Date: 2024-05-26 08:52:59
 * @Description: 
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-05-26 09:54:08
 */
#include <atomic>
#include <thread>
#include <vector>
#include <iostream>

class AtomicCounter
{
public:
    void RunTest(uint32_t uiThreadNum)
    {
        auto threadFunc = [&]()
        {
            uint32_t uiCount = 0;
            while (uiCount++ < 1000000)
            {
                this->m_ui64Counter.fetch_add(1, std::memory_order::memory_order_relaxed);
            }
        };

        for (uint32_t uiIndex = 0; uiIndex < uiThreadNum; uiIndex++)
        {
            m_vecThreads.push_back(std::thread(threadFunc));
        }


        for (auto& refThread : m_vecThreads)
        {
            refThread.join();
        }

        std::cout << "Counter: " << m_ui64Counter.load() << std::endl;
    }
private:
    std::vector<std::thread> m_vecThreads;    
    std::atomic<uint64_t>    m_ui64Counter;
};

int main(int argc, char** argv)
{
    AtomicCounter objCounter;

    if (argc < 2)
    {
        std::cout << "Usage: " << argv[0] << " thread-number" << std::endl;
        return 0;
    }

    objCounter.RunTest(atoi(argv[1]));

    return 0;
}